关于 Elasticsearch 段合并,这一篇说透了!
0、事出有因
您好,目前我需要将只读索引segment合并,有几个问题想要求教
1、 segment是不是合并到一个最好,及max_num_segments=1 2、合并的时候,通过 POST /my_index/_forcemerge?max_num_segments=1
会不会吃光所有的机器资源,造成服务暂时不可用(optimize?max_num_segments=1就会吃光所有资源),但是我没有从官方文档找到_forcemerger 这种方式的资源消耗。
3、在es 6.7及以上中index.merge 相关参数有需要特别注意和调整的地方吗? (目前我全部使用的默认值)
死磕 Elasticsearch 知识星球 http://t.cn/RmwM3N9
这个涉及到基础概念,为保证说法的准确性,如下会贴上官方链接和其他来源地址,以便更深入理解好段合并的相关知识。
1、什么是段?
图片来源:https://medium.com/@hansrajchoudhary_88463/
如图所示,自顶向下看,
一个集群包含1个或多个节点; 一个节点包含1个或多个索引; 一个索引:类似 Mysql 中的数据库; 每个索引又由一个或多个分片组成; 每个分片都是一个 Lucene 索引实例,您可以将其视作一个独立的搜索引擎,它能够对 Elasticsearch 集群中的数据子集进行索引并处理相关查询; 每个分片包含多个segment(段),每一个segment都是一个倒排索引。
在查询的时,会把所有的segment查询结果汇总归并为最终的分片查询结果返回。
2、为什么 段是不可变的?
在 lucene 中,为了实现高索引速度,故使用了segment 分段架构存储。
一批写入数据保存在一个段中,其中每个段是磁盘中的单个文件。
由于两次写入之间的文件操作非常繁重,因此将一个段设为不可变的,以便所有后续写入都转到New段。
3、什么是段合并?
由于自动刷新流程每秒会创建一个新的段(由动态配置参数:refresh_interval 决定),这样会导致短时间内的段数量暴增。
而段数目太多会带来较大的麻烦。
消耗资源:每一个段都会消耗文件句柄、内存和cpu运行周期; 搜索变慢:每个搜索请求都必须轮流检查每个段;所以段越多,搜索也就越慢。
Elasticsearch 通过在后台进行段合并来解决这个问题。
小的段被合并到大的段,然后这些大的段再被合并到更大的段。
4、段合并做了什么?
段合并的时候会将那些旧的已删除文档从文件系统中清除。
被删除的文档(或被更新文档的旧版本)不会被拷贝到新的大段中。
启动段合并不需要你做任何事。进行索引和搜索时会自动进行。
当索引的时候,刷新(refresh)操作会创建新的段并将段打开以供搜索使用。 合并进程选择一小部分大小相似的段,并且在后台将它们合并到更大的段中。这并不会中断索引和搜索。
5、为什么要进行段合并?
索引段的个数越多,搜索性能越低并且消耗更多的内存。
索引段是不可变的,你并不能物理上从中删除信息。
可以物理上删除document,但只是做了删除标记,物理上并没有删除。
当段合并时,这些被标记为删除的文档并没有被拷贝至新的索引段中,这样,减少了最终的索引段中的 document 数目。
6、段合并的好处是什么?
减少索引段的数量并提高检索速度;
减少索引的容量(文档数)
原因:段合并会移除被标记为已删除的那些文档。
7、段合并可能带来的问题?
磁盘IO操作的代价;
速度慢的系统中,段合并会显著影响性能。
8、关于合并段的大小(通常为1个)——针对问题1
早期版本的文档有说明如下:
optimize API(现在已废弃,原理一致)
optimize API大可看做是 强制合并 API。它会将一个分片强制合并到 max_num_segments 参数指定大小的段数目。
这样做的意图是减少段的数量(通常减少到一个),来提升搜索性能。
9、关于段合并资源消耗——针对问题2
资源消耗的官方解读
orce merge should only be called against an index after you have finished writing to it. Force merge can cause very large (>5GB) segments to be produced, and if you continue to write to such an index then the automatic merge policy will never consider these segments for future merges until they mostly consist of deleted documents. This can cause very large segments to remain in the index which can result in increased disk usage and worse search performance.
一句话:导致磁盘io消耗和影响检索性能。
Force merge API
https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html
以下是老版本文档解读,原理一致可参考,api已过时。
段合并
https://www.elastic.co/guide/cn/elasticsearch/guide/current/merge-process.html
请注意,使用 optimize API 触发段合并的操作不会受到任何资源上的限制。
这可能会消耗掉你节点上全部的 I/O 资源, 使其没有“富裕”资源来处理搜索请求,从而有可能使集群失去响应。
如果你想要对索引执行 optimize,你需要先使用分片分配(查看 迁移旧索引)把索引移到一个安全的节点,再执行。
是的,非常耗费资源,建议在非业务密集实践操作。
我的线上环境,我都是凌晨1点段合并(脚本控制,晚上没人操作系统)
10、可推荐的参数——针对问题3
减少段的产生频率,修改refresh_inteval:默认1s,如果时效性要求不高,建议改成30s。
index.merge.scheduler.max_thread_count:根据cpu核数修改
推荐:
https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html
老版本参数修改参考价值不大,也建议看一下:
索引性能技巧
https://www.elastic.co/guide/cn/elasticsearch/guide/current/indexing-performance.html#segments-and-merging
参考
1、https://medium.com/@hansrajchoudhary_88463/elasticsearch-things-you-should-know-about-es-to-be-useful-fbc537a04086
2、https://stackoverflow.com/questions/30151566/why-are-documents-in-elasticsearch-immutable
3、https://www.elastic.co/cn/blog/found-elasticsearch-from-the-bottom-up
推荐:
你的 Elasticsearch 难题,官方文档早就有了答案......
更短时间更快习得更多干货!
中国40%+Elastic认证工程师出自于此!